/* Copyright (C) 2010 Fredrique Samuels, fredriquesamuels@gmail.com */

/*
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "checkbox.h"



namespace tri {
namespace ui {


extCheckBox::extCheckBox() : 
	tri::ui::extButton(), mChecked(false), mButtonGroup(NULL){
	mCheckBoxListener = new CheckBoxListener(this);
	setStyle("DefaultCheckBoxStyle");
}

extCheckBox::~extCheckBox() {
	delete mCheckBoxListener;
	if (mButtonGroup != NULL){
		mButtonGroup->remove(this);
	}
}

bool  extCheckBox::selected(){
	return mChecked;
}

void extCheckBox::setSelected(bool b){
	if (b != mChecked){
		mChecked = b;
		emit(tri::VALUE_CHANGED);
	}
}


bool extCheckBox::updateStyle(){
	tri::ui::extButton::updateStyle();
	if(selected()){
		tri::ui::extButton::applyStyle(tri::CHECKED);
	}
	return false;
}

extCheckBox::CheckBoxListener::CheckBoxListener(extCheckBox* box) :mBox(box){
	mBox = box;
	if(mBox !=NULL){
		mBox->connect<CheckBoxListener>(tri::CLICKED,this,&CheckBoxListener::onCheckBoxChange);
	}
}

void extCheckBox::CheckBoxListener::onCheckBoxChange(){
	if(mBox !=NULL){
		mBox->setSelected(!mBox->selected());
		//mBox->setEventState(tri::CHECKED);
		
	}
}


//===============================================

extButtonGroup::extButtonGroup(){}
extButtonGroup::~extButtonGroup(){
	removeAll();
}

int extButtonGroup::find(extCheckBox* b){
	std::vector<extCheckBox*>::iterator it;
	int index = -1;
	int ret = -1;
	
	for ( it=mButtonList.begin() ; it < mButtonList.end(); it++ ){
		index++;
		if( (*it) == b ){
			ret = index;
			break;
		}
	}
	return ret;
}
	
void extButtonGroup::addCheckBoxToGroup(extCheckBox* b){
	if(b==NULL){
		return;
	}
	if (find(b) == -1 ){
		if (b->mButtonGroup != NULL){
			b->mButtonGroup->removeFromGroup(find(b));
		}
		
		mButtonList.push_back(b);
		b->SELECTION_CHANGE.connect(this,&extButtonGroup::selectionChanged);
		b->mButtonGroup = this;
	}
}

void extButtonGroup::remove(extCheckBox* ret){
	if(ret->mButtonGroup == this){
		ret->SELECTION_CHANGE.disconnect(this);
		ret->mButtonGroup = NULL;
	}
}

extCheckBox* extButtonGroup::removeFromGroup(int index){
	extCheckBox* ret = NULL;
	if (mButtonList.size() > index && index  > -1 ){
		ret = mButtonList[index];
		ret->SELECTION_CHANGE.disconnect(this);
		ret->mButtonGroup = NULL;
	}
	
	return ret;
}

void extButtonGroup::removeAll(){
	std::vector<extCheckBox*>::iterator it;
	for ( it=mButtonList.begin() ; it < mButtonList.end(); it++ ){
		(*it)->SELECTION_CHANGE.disconnect(this);
		(*it)->mButtonGroup = NULL;
	}
}


void extButtonGroup::setActive(int index){
	if (mButtonList.size() > index && index  > -1 ){
		for (int i = 0;i < (int)mButtonList.size() ; i++){
			if(i != index){
				mButtonList[i]->setSelected(false);
			}else{
				if (!mButtonList[i]->selected()){
					mButtonList[i]->setSelected(true);
				}
			}
		}
	}
}

unsigned int extButtonGroup::size(){
	return mButtonList.size();
}
	
void extButtonGroup::selectionChanged(extCheckBox* b){
	if (b->selected()){
		setActive(find(b));
		b->emit(tri::VALUE_CHANGED);
	}
}

extCheckBox*  extButtonGroup::getSelected(){
	std::vector<extCheckBox*>::iterator it;
	for ( it=mButtonList.begin() ; it < mButtonList.end(); it++ ){
		if( (*it)->selected() ){
			return (*it);
		}
	}
	return NULL;
}

}
}
